package rpc.frame.core.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.util.Map;

/**
 * 获取spring的 context 获取容器的属性
 */
@Component("springBeanFactory")
public class SpringBeanFactory implements ApplicationContextAware {

    /**
     * IOC 容器
     */
    private static ApplicationContext context;
    @Override
    public  void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context=applicationContext;
    }

    /**
     * 根据类 的类型返回bean
     * @param c
     * @return
     * @param <T>
     */
    public static <T> T getBean(Class<T> c){
        return context.getBean(c);
    }

    /**
     * 根据bean的名称 获取bean
     * @param beanName
     * @return
     */
    public static Object getBean(String beanName){
        return  context.getBean(beanName);
    }

    /**
     * 获取指定注解的bean
     * @param annotationClass
     * @return
     */
    public static Map<String,Object> getBeanListByAnnotationClass(Class<? extends Annotation> annotationClass){
        return context.getBeansWithAnnotation(annotationClass);
    }

    /**
     * 向容器中注册某个bean 并且增强
     * @param bean
     */
    public static void registerSingleton(Object bean){
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
        // 让bean完成Spring初始化过程中所有增强器检验，只是不重新创建bean
        beanFactory.applyBeanPostProcessorsAfterInitialization(bean,bean.getClass().getName());
        //将bean以单例的形式入驻到容器中，此时通过bean.getClass().getName()或bean.getClass()都可以拿到放入Spring容器的Bean
        beanFactory.registerSingleton(bean.getClass().getName(),bean);
    }
}
